﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace PyramidShadow
{
    class PlayerAnimation
    {
        //If tis value gets changed, the logic as well as enum.Direction needs also to be changed!
        // 4 Cirections and 1 for None
        private const byte NUM_OF_DIRS = 5;
        
        
        // The image representing the collection of images used for animation
        Texture2D spriteStrip;
        // The time since we last updated the frame
        int elapsedTime;
        // The time we display a frame until the next one
        int frameTime;
        // The number of columns that the animation contains
        int columnCount;
        // The number of rows that the animation contains
        int rowCount;
        // The index of the current Column we are displaying
        int currentColumn;
        // The index of the current Row we are displaying
        int currentRow;
        // The area of the image strip we want to display
        Rectangle sourceRect;
        // The area where we want to display the image strip in the game
        Rectangle destinationRect;
        // The state of the Animation
        public bool Active;

        private Direction[] dirsToRow;

        public PlayerAnimation(Texture2D texture, Vector2 position,
                                int frameWidth, int frameHeight, int columnCount, int frametime)
        {
            // Keep a local copy of the values passed in
            this.columnCount = columnCount;
            rowCount = NUM_OF_DIRS;
            this.frameTime = frametime;
            
            dirsToRow = new Direction[NUM_OF_DIRS];
            int i = 0;
            foreach(Direction dir in Enum.GetValues(typeof(Direction)))
            {
                if(i < (NUM_OF_DIRS))
                    dirsToRow[i] = dir;
                i++;
            }

            /*
             * Here we got following array indices for Directions:
             * 0=Up,
             * 1=Down,
             * 2=Left,
             * 3=Right,
             * 4=None
             * 
             * This is essential for the Spritesheet Designers, because this order is in the logic used.
             * So first row are the animations for walking up, second for down,...
             */
            spriteStrip = texture;
            sourceRect = new Rectangle((int)position.X, (int)position.Y, frameWidth, frameHeight);

            // Set the time to zero
            elapsedTime = 0;
            currentColumn = 0;
            currentRow = 0;

            // Set the Animation to active by default
            Active = true;
        }

        public void Update(GameTime gameTime, KeyboardState currentKeyboardState, Rectangle boundingBox)
        {
            Direction dir = Direction.None;
            Keys[] keys = currentKeyboardState.GetPressedKeys();
            bool flag = false; // Checks for a hit in our key collection

            for (int i = 0; i < keys.Length; i++)
            {
                switch (keys[i])
                {
                    case Keys.Up:

                        dir = Direction.Up;
                        flag = true;
                        break;
                    case Keys.Down:
                        dir = Direction.Down;
                        flag = true;
                        break;

                    case Keys.Left:
                        dir = Direction.Left;
                        flag = true;
                        break;

                    case Keys.Right:
                        dir = Direction.Right;
                        flag = true;
                        break;

                    default: dir = Direction.None;
                        break;
                }

                if (flag)
                    break; //Got a hit, so continue

            }
            
            for (int i = 0; i < NUM_OF_DIRS; i++)
            {
                if (dir == dirsToRow[i])
                    currentRow = i;
            }

            //Double check for no input,if so:
            //Player stoped or isn't Moving, back to the first Frame and ignore elapsed time.
            if(currentRow == NUM_OF_DIRS-1 && dir == Direction.None)
            {
                currentColumn = 0;
                return;
            }

            
            elapsedTime += (int)gameTime.ElapsedGameTime.TotalMilliseconds;

            if (elapsedTime > frameTime)
            {
                // Move to the next frame
                currentColumn++;

                // If the currentFrame is equal to frameCount reset currentFrame to zero
                if (currentColumn == columnCount)
                {
                    currentColumn = 0;
                }
                // Reset the elapsed time to zero
                elapsedTime = 0;
            }

            // Calculate the correct frame in the image strip
            sourceRect.X = currentColumn * sourceRect.Width;
            sourceRect.Y = currentRow * sourceRect.Height;

            // use the boundingBox for finding the place to draw, so we don't need to calculate it again
            destinationRect = boundingBox;

        }

        // Draw the Animation Strip
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(spriteStrip, destinationRect, sourceRect, Color.White);
        }
    }
}
